home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-15 | 55.6 KB | 1,468 lines |
- /*****************************************************************************
- *
- * MODULE NAME: CPICERR.C
- *
- * COPYRIGHTS:
- * This module contains code made available by IBM
- * Corporation on an AS IS basis. Any one receiving the
- * module is considered to be licensed under IBM copyrights
- * to use the IBM-provided source code in any way he or she
- * deems fit, including copying it, compiling it, modifying
- * it, and redistributing it, with or without
- * modifications. No license under any IBM patents or
- * patent applications is to be implied from this copyright
- * license.
- *
- * A user of the module should understand that IBM cannot
- * provide technical support for the module and will not be
- * responsible for any consequences of use of the program.
- *
- * Any notices, including this one, are not to be removed
- * from the module without the prior written consent of
- * IBM.
- *
- * AUTHOR: Peter J. Schwaller
- * VNET: PJS at RALVM6 Tie Line: 444-4376
- * Internet: pjs@ralvm6.vnet.ibm.com (919) 254-4376
- * John Q. Walker
- * VNET: JOHNQ at RALVM6 Tie Line: 444-4414
- * Internet: johnq@ralvm6.vnet.ibm.com (919) 254-4414
- *
- * FUNCTION: Contains procedures to be called for handling
- * unexpected CPI-C return codes.
- * Contains procedures to be called for handling the
- * CPI-C error information cpicerr.
- *
- * AVAILABILITY:
- * These sample programs and source are also available on
- * CompuServe through the APPC Information Exchange. To get
- * to the APPC forum just type 'GO APPC' from any CompuServe
- * prompt. The samples are available in the Sample Programs
- * library section. Just search on the keyword CPICPGMS to
- * find all the samples in this series.
- *
- * Updates for the sample programs and support for many more
- * CPI-C platforms will also be made available on CompuServe.
- *
- * RELATED FILES:
- * CPICERR.H
- *
- *****************************************************************************/
-
- /*****************************************************************************
- *
- * OVERVIEW OF CPICERR CALLS
- *
- * cpicerr_new() Creates a CPICERR object.
- * This must be done before any other
- * cpicerr calls can be used.
- *
- * These calls set values in the cpicerr object structure and affect how
- * cpicerr_handle_rc reacts to errors.
- *
- * cpicerr_set_conv_id() Used to extract conversation state info
- * cpicerr_set_exit_level() Level of error on which to exit
- * cpicerr_set_log_file_name() What filename to use for logging
- * cpicerr_set_log_file_path() Where the filename is
- * cpicerr_set_log_level() Level of error on which to log errors
- * cpicerr_set_major_version() 8 bit int - see cpicerr_exchange_version
- * cpicerr_set_minor_version() 8 bit int - see cpicerr_exchange_version
- * cpicerr_set_program_name() String - Output as part of log info
- * cpicerr_set_program_info() String - Output as part of log info
- * cpicerr_set_show_level() Level of error on which to show errors
- *
- * cpicerr_handle_rc() Should be called by the program for all
- * UNEXPECTED return codes.
- * Functions performed are:
- * Classification of the return code
- * Showing partial info to end user
- * Logging complete info to disk
- *
- * cpicerr_exchange_version() Exchanges version numbers with the
- * partner. Very useful when supporting
- * multiple versions of a program.
- *
- * cpicerr_destroy() Destroys the CPICERR object.
- *
- *
- * cpicerr_classify_rc() These are internal calls used by
- * cpicerr_show_rc() other cpicerr_handle_rc.
- * cpicerr_log_cpicerr()
- * cpicerr_get_message()
- * cpicerr_free_cpicerr()
- * cpicerr_set_rc_info()
- * cpicerr_show_product_info()
- *
- *****************************************************************************/
-
- /* My CPI-C include file */
- /* Hides CMC.H differences among platforms */
- #include "cpiccmc.h"
-
- #ifdef GET_OS2_SENSE_DATA
- #include <appc_c.h>
- #endif
-
- /* Collection of routines with special ported version for each platform */
- #include "cpicport.h"
-
- #include <stdio.h> /* C library includes */
- #include <stdlib.h>
- #include <string.h>
-
- #ifndef TIME_NOT_SUPPORTED
- #include <time.h>
- #endif
-
-
- #include "cpicerr.h" /* CPI-C error handling vars. */
-
-
- /*****************************************************************************
- *
- * cpicerr_new()
- *
- * Usage:
- * This function creates a CPICERR object which should be used on all
- * subsequent calls to cpicerr. If an error occurs and a valid object
- * cannot be created, NULL will be returned.
- *
- *****************************************************************************/
- CPICERR *
- cpicerr_new(void)
- {
- CPICERR * cpicerr;
-
- cpicerr = (CPICERR *) malloc(sizeof(*cpicerr));
- if (cpicerr == NULL) {
- return NULL;
- }
-
- /*-----------------------------------------------------------------------*
- * Zero out the whole cpicerr.
- * This is a failsafe for any fields in CPICERR which we don't explicitly
- * initialize to a value.
- *-----------------------------------------------------------------------*/
- memset((void *)cpicerr,
- (int)0,
- (size_t)sizeof(CPICERR));
-
- /*-----------------------------------------------------------------------*
- * Save the time of program initialization.
- *-----------------------------------------------------------------------*/
- #ifndef TIME_NOT_SUPPORTED
- time(&(cpicerr->program_start_time));
- #endif
-
- /*-----------------------------------------------------------------------*
- * Indicate that the conversation id field has not been set.
- *-----------------------------------------------------------------------*/
- cpicerr->conv_id_set = FALSE;
-
- /*-----------------------------------------------------------------------*
- * Initialize version levels. 0 indicates they have not been set.
- *-----------------------------------------------------------------------*/
- cpicerr->major_version = 0;
- cpicerr->minor_version = 0;
-
- /*-----------------------------------------------------------------------*
- * Initialize to always exit after an error occurs.
- *-----------------------------------------------------------------------*/
- cpicerr->exit_level = ALL_ERRORS;
-
- /*-----------------------------------------------------------------------*
- * Initialize to always show errors.
- *-----------------------------------------------------------------------*/
- cpicerr->show_level = ALL_ERRORS;
-
- /*-----------------------------------------------------------------------*
- * Initialize to always log errors.
- *-----------------------------------------------------------------------*/
- cpicerr->log_level = ALL_ERRORS;
-
- /*-----------------------------------------------------------------------*
- * Initialize strings to NULL in case 0 != NULL
- *-----------------------------------------------------------------------*/
- cpicerr->program_name = NULL;
- cpicerr->program_info = NULL;
- cpicerr->log_file_name = NULL;
- cpicerr->log_file_path = NULL;
-
- return cpicerr;
- }
-
- /*****************************************************************************
- *
- * cpicerr_set_conv_id
- *
- * Usage:
- * This call should be used just before the cmallc call (for clients),
- * or just after the cmaccp call (for servers).
- *
- * This routine will save the conversation id, as well as partner information
- * and conversation status which can be extracted from CPI-C.
- *
- * This information is often helpful for debugging and in many cases cannot
- * be obtained after an error occurs, since you no longer have a valid
- * conversation id after the conversation has been deallocated.
- *
- *****************************************************************************/
- int
- cpicerr_set_conv_id(CPICERR * cpicerr,
- unsigned char * cm_conv_id)
- {
- CM_RETURN_CODE conv_rc; /* Return code from CPI-C call */
- CM_SYNC_LEVEL sync_level;
- int rc; /* return value for function */
- CM_CONVERSATION_TYPE conversation_type;
-
-
- if (cpicerr != (CPICERR *)NULL) {
- /*-------------------------------------------------------------------*
- * Save the conversation ID.
- * This can often be used in conjunction with error logs or trace
- * utilities.
- *-------------------------------------------------------------------*/
- memcpy(cpicerr->conversation_id,
- cm_conv_id,
- sizeof(cpicerr->conversation_id));
-
- /*-------------------------------------------------------------------*
- * Extract the conversation type.
- * Not all CPI-C implementations support Extract_Conversation_State.
- * The #define statement for ECT_NOT_SUPPORTED is in CPICCMC.H.
- *-------------------------------------------------------------------*/
- #ifndef ECT_NOT_SUPPORTED
- cmect(cm_conv_id, /* Current conversation ID */
- &conversation_type, /* Returned conversation type */
- &conv_rc); /* Put the return code here */
- if (conv_rc == CM_OK)
- cpicerr->conversation_type = conversation_type;
- #else
- cpicerr->conversation_type = CMECT_NOT_SUPPORTED;
- #endif
-
- /*-------------------------------------------------------------------*
- * Extract the mode name used for this conversation.
- *-------------------------------------------------------------------*/
- cmemn(cm_conv_id, /* Current conversation ID */
- cpicerr->mode_name, /* Returned mode name */
- &(cpicerr->mode_name_length), /* Returned mode name length */
- &conv_rc); /* Put the return code here */
- if (conv_rc == CM_OK) {
- cpicerr->mode_name[(int)cpicerr->mode_name_length] = '\0';
- }
-
- /*-------------------------------------------------------------------*
- * Extract the partner's LU name.
- *-------------------------------------------------------------------*/
- cmepln(cm_conv_id, /* Current conversation ID */
- cpicerr->partner_LU_name, /* Returned partner LU */
- &(cpicerr->partner_LU_name_length),/* Partner LU name length */
- &conv_rc); /* Put the return code here */
- if (conv_rc == CM_OK) {
- cpicerr->partner_LU_name[(int)cpicerr->partner_LU_name_length]
- = '\0';
- }
-
- /*-------------------------------------------------------------------*
- * Extract the conversation sync level.
- *-------------------------------------------------------------------*/
- cmesl(cm_conv_id, /* Current conversation ID */
- &sync_level, /* Returned sync level */
- &conv_rc); /* Put the return code here */
- if (conv_rc == CM_OK)
- cpicerr->sync_level = sync_level;
-
- rc = 0;
- } else {
- rc = 1;
- }
- return rc;
- }
-
- /*****************************************************************************
- *
- * cpicerr_set_exit_level
- *
- * Usage:
- * Specify the CPI-C error classification as the exit level.
- * When cpicerr_handle_rc() is called, the return code will be classified.
- * If the classification is above the exit level, the program will be
- * terminated (after conversation cleanup).
- *
- * A value of ALL_ERRORS can be used to force an exit on any call to
- * cpicerr_handle_rc(). This is the DEFAULT value.
- *
- * A value of NO_ERRORS can be used to indicate that cpicerr should never
- * cause an exit. Your application should handle all exit termination.
- * This is especially useful when using more than one conversation.
- *
- * Also see:
- * cpicerr_set_log_level
- * cpicerr_set_show_level
- *****************************************************************************/
- int
- cpicerr_set_exit_level(CPICERR * cpicerr,
- CPIC_RC_HANDLING exit_level)
- {
- cpicerr->exit_level = exit_level;
- return 0;
- }
-
- /*****************************************************************************
- *
- * cpicerr_set_log_file_name
- *
- * Usage:
- * Sets the name of the log file to be used in cpicerr_handle_rc() to
- * log complete error information. No attempt is made to verify that
- * the log_file_name specified is a valid filename or whether the file
- * can be opened. If the log_file_name cannot be opened when logging
- * needs to be done, all log output will be sent to stderr instead.
- *
- * For environments that support directory structures, you should specify
- * the filename on cpicerr_set_log_file_name and the directory on
- * cpicerr_set_log_file_path. This allows your program to be isolated
- * from changes in environments that only support a single level
- * of directory (for example, VM).
- *
- * Also see:
- * cpicerr_set_log_file_path
- * cpicerr_log_cpicerr (internal)
- *****************************************************************************/
- cpicerr_set_log_file_name(CPICERR * cpicerr,
- char * log_file_name)
- {
- /*-----------------------------------------------------------------------*
- * Initialize the name of the log file.
- *-----------------------------------------------------------------------*/
- cpicerr->log_file_name = (char *) malloc(strlen(log_file_name)+1);
- if (cpicerr->log_file_name != NULL) {
- strcpy(cpicerr->log_file_name, log_file_name);
- return 0;
- } else {
- return 1;
- }
-
- }
-
- /*****************************************************************************
- *
- * cpicerr_set_log_file_path
- *
- * Usage:
- * Specifies the path qualifier for the log file name specified in the
- * cpicerr_set_log_file_name call. If cpicerr_set_log_file_path is used
- * without setting the log file name, no error logging will occur.
- *
- * If you specify a string whose first character is a $, the rest of the
- * string will be looked for as an environment variable. For example,
- * in OS/2, you put the following in your CONFIG.SYS:
- * SET LOGPATH=d:\logfiles
- *
- * then specify $LOGPATH as a parameter on cpicerr_set_log_file_path.
- *
- *****************************************************************************/
- cpicerr_set_log_file_path(CPICERR * cpicerr,
- char * log_file_path)
- {
- char * path;
-
- /*-----------------------------------------------------------------------*
- * Initialize the name of the log file.
- *-----------------------------------------------------------------------*/
- if (log_file_path[0] == '$') {
- path = getenv(&log_file_path[1]);
- if (path == NULL) {
- return 1;
- }
- } else {
- path = log_file_path;
- }
-
- cpicerr->log_file_path = (char *) malloc(strlen(path)+1);
- if (cpicerr->log_file_path != NULL) {
- strcpy(cpicerr->log_file_path, path);
- return 0;
- } else {
- return 1;
- }
-
- }
-
- /*****************************************************************************
- *
- * cpicerr_set_log_level
- *
- * Usage:
- * Specify the CPI-C error classification as the log level.
- * When cpicerr_handle_rc() is called, the return code will be classified.
- * If the classification is above the log level, the return code and
- * conversation information will be logged to the log file specified
- * with the cpicerr_set_log_file_name and cpicerr_set_log_file_path.
- *
- * A value of ALL_ERRORS can be used to force logging on any call to
- * cpicerr_handle_rc(). This is the DEFAULT value. This is especially
- * useful when used on servers.
- *
- * A value of NO_ERRORS can be used to indicate that cpicerr should never
- * cause an error log. Your application should handle all error logging.
- *
- * Also see:
- * cpicerr_set_log_file_name
- * cpicerr_set_log_file_path
- * cpicerr_log_cpicerr (internal)
- * cpicerr_set_exit_level
- * cpicerr_set_show_level
- *****************************************************************************/
- int
- cpicerr_set_log_level(CPICERR * cpicerr,
- CPIC_RC_HANDLING log_level)
- {
- cpicerr->log_level = log_level;
- return 0;
- }
-
- /*****************************************************************************
- *
- * cpicerr_set_major_version
- *
- * Usage:
- * Sets the major version number for the application.
- * The version number can be 0-255.
- *
- * The version number is used on error logging and by the
- * cpicerr_exchange_version() call.
- *
- * Also see:
- * cpicerr_set_minor_version
- *****************************************************************************/
- int cpicerr_set_major_version( CPICERR * cpicerr,
- char major_version)
- {
- cpicerr->major_version = major_version;
- return 0;
- }
-
- /*****************************************************************************
- *
- * cpicerr_set_minor_version
- *
- * Usage:
- * Sets the minor version number for the application.
- * The version number can be 0-255.
- *
- * The version number is used on error logging and by the
- * cpicerr_exchange_version() call.
- *
- * Also see:
- * cpicerr_set_major_version
- *****************************************************************************/
- int cpicerr_set_minor_version( CPICERR * cpicerr,
- char minor_version)
- {
- cpicerr->minor_version = minor_version;
- return 0;
- }
-
-
- /*****************************************************************************
- *
- * cpicerr_set_program_info
- *
- * Usage:
- * Sets a program information string that is included in the log information.
- *****************************************************************************/
- cpicerr_set_program_info( CPICERR * cpicerr,
- char * program_info)
- {
- /*-----------------------------------------------------------------------*
- * Save the application's program information string
- *-----------------------------------------------------------------------*/
- cpicerr->program_info = (char *) malloc(strlen(program_info)+1);
- if (cpicerr->program_info != NULL) {
- strcpy(cpicerr->program_info, program_info);
- return 0;
- } else {
- return 1;
- }
- }
-
-
- /*****************************************************************************
- *
- * cpicerr_set_program_name
- *
- * Usage:
- * Sets a program name string that is included in the log information.
- *****************************************************************************/
- cpicerr_set_program_name(CPICERR * cpicerr,
- char * program_name)
- {
- /*-----------------------------------------------------------------------*
- * Save the local program name.
- *-----------------------------------------------------------------------*/
- cpicerr->program_name = (char *) malloc(strlen(program_name)+1);
- if (cpicerr->program_name != NULL) {
- strcpy(cpicerr->program_name, program_name);
- return 0;
- } else {
- return 1;
- }
- }
-
-
- /*****************************************************************************
- *
- * cpicerr_set_show_level
- *
- * Usage:
- * Specify the CPI-C error classification as the show level.
- * When cpicerr_handle_rc() is called, the return code will be classified.
- * If the classification is above the show level, the return code and
- * some conversation information will be shown to the user.
- *
- * A value of ALL_ERRORS can be used to force showing of all calls to
- * cpicerr_handle_rc(). This is the DEFAULT value.
- *
- * A value of NO_ERRORS can be used to indicate that cpicerr should never
- * cause an error to be shown to the user.
- *
- * Also see:
- * cpicerr_set_exit_level
- * cpicerr_set_log_level
- *****************************************************************************/
- int
- cpicerr_set_show_level(CPICERR * cpicerr,
- CPIC_RC_HANDLING show_level)
- {
- cpicerr->show_level = show_level;
- return 0;
- }
-
-
- /******************************************************************************
- *
- * cpicerr_handle_rc
- *
- * Usage:
- * This function should be called to handle any unexpected CPI-C return
- * codes. The exact function of this routine depends upon the settings
- * that have been made to the CPICERR object.
- *
- * Functions include:
- * Determining the current conversation state
- * Classifying the return code (CPIC_RC_HANDLING enum)
- * Showing return code info to the user
- * Logging the return code and conversation info to disk
- * Deallocate the conversation and exit
- *
- * Also see:
- * cpicerr_set_exit_level
- * cpicerr_set_log_level
- * cpicerr_set_show_level
- *
- *****************************************************************************/
- CPIC_RC_HANDLING
- cpicerr_handle_rc(CPICERR * cpicerr,
- CPIC_VERB_INDEX verb_index,
- CM_RETURN_CODE conv_rc)
-
- {
- /* Displays the CPI-C return code and the verb name. */
-
- CM_RETURN_CODE cm_rc; /* Return code from CPI-C call */
- CPIC_RC_HANDLING classification; /* Returned RC classification */
- char * string; /* temp var for output strings */
- FILE *target_file; /* where to send messages */
- CM_CONVERSATION_STATE conversation_state; /* Current conv. state */
-
- /*-----------------------------------------------------------------------*
- * Extract the current conversation state.
- * This will not be useful if the conversation has failed or a deallocate
- * return code has been received. The conversation state is most useful
- * when a state check has occurred.
- *-----------------------------------------------------------------------*/
- #ifndef ECS_NOT_SUPPORTED
- cmecs(cpicerr->conversation_id,
- &conversation_state,
- &cm_rc);
- if (cm_rc == CM_OK) {
- cpicerr->conversation_state = conversation_state;
- }
- #else
- cpicerr->conversation_state = CMECS_NOT_SUPPORTED;
- #endif
-
- /*-----------------------------------------------------------------------*
- * Store the error information in the cpicerr
- *-----------------------------------------------------------------------*/
- cpicerr_set_rc_info(cpicerr, verb_index, conv_rc);
-
- /*-----------------------------------------------------------------------*
- * Set the target for the printed information about the error.
- *-----------------------------------------------------------------------*/
- target_file = stderr;
-
- /*-----------------------------------------------------------------------*
- * Get the classification for this return code.
- *-----------------------------------------------------------------------*/
- cpicerr_classify_rc(conv_rc, &classification);
-
- /*-----------------------------------------------------------------------*
- * Show the CPI-C verb and return code.
- *-----------------------------------------------------------------------*/
- if (classification >= cpicerr->show_level) {
- cpicerr_show_rc(cpicerr, target_file);
- }
-
-
- /*-----------------------------------------------------------------------*
- * Show the classification for this return code.
- *-----------------------------------------------------------------------*/
- if (classification >= cpicerr->show_level) {
- string = cpicerr_get_message(CPIC_RC_CLASSES, classification);
- fprintf(target_file, " return code class: %s\n",
- string);
- /*-----------------------------------------------------------------------*
- * Show product specific information associated with this error.
- *-----------------------------------------------------------------------*/
- cpicerr_show_product_info(cpicerr, target_file);
- }
-
-
- /*-----------------------------------------------------------------------*
- * Log this error, along with the infomation in its cpicerr.
- *-----------------------------------------------------------------------*/
- if (classification >= cpicerr->log_level) {
- cpicerr_log_cpicerr(cpicerr);
- }
-
-
- if (classification >= cpicerr->exit_level) {
- CM_INT32 deallocate_type;
- /*-------------------------------------------------------------------*
- * Exit the application, rather than returning to the caller.
- *-------------------------------------------------------------------*/
- deallocate_type = CM_DEALLOCATE_ABEND;
-
- cmsdt(cpicerr -> conversation_id,
- &deallocate_type,
- &cm_rc);
-
- cmdeal(cpicerr -> conversation_id,
- &cm_rc);
-
- exit(EXIT_FAILURE); /* Set a failure return code */
- }
- return classification;
- }
-
-
- /******************************************************************************
- *
- * cpicerr_exchange_version
- *
- *****************************************************************************/
-
- int
- cpicerr_exchange_version(CPICERR * cpicerr,
- unsigned char * cm_conv_id,
- CM_INT32 conv_state,
- char * partner_major_version,
- char * partner_minor_version)
- {
- CM_SEND_TYPE send_type; /* CPI-C send type */
- CM_PREPARE_TO_RECEIVE_TYPE prep_to_receive; /* CPI-C prepare to receive */
- CM_INT32 cm_rc; /* CPI-C return code */
- CM_INT32 length; /* generic length variable */
- CM_INT32 rts_received; /* request to send received */
- CM_INT32 max_receive_len; /* Max receive length on CMRCV */
- CM_INT32 what_received; /* What received parm from CMRCV */
- CM_INT32 received_len; /* Amount of data rcvd on CMRCV */
- CM_INT32 status_received; /* Status from CMRCV */
- unsigned char buffer[128]; /* data buffer */
-
- *partner_major_version = 0;
- *partner_minor_version = 0;
-
- prep_to_receive = CM_PREP_TO_RECEIVE_FLUSH;
- cmsptr(cm_conv_id, /* Set prepare to receive type */
- &prep_to_receive,
- &cm_rc);
- /* The only expected return code is CM_OK */
- if (cm_rc != CM_OK) return cpicerr_handle_rc(cpicerr, MSG_CMSPTR, cm_rc);
-
- send_type = CM_BUFFER_DATA;
- cmsst(cm_conv_id, /* Set send type */
- &send_type,
- &cm_rc);
- if (cm_rc != CM_OK) return cpicerr_handle_rc(cpicerr, MSG_CMSST, cm_rc);
-
-
- switch (conv_state) {
- case CM_SEND_STATE:
- buffer[0] = CPICERR_EXCHANGE_VERSION;
- buffer[1] = cpicerr->major_version;
- buffer[2] = cpicerr->minor_version;
- length = 3;
- cmsend(cm_conv_id,
- buffer,
- &length,
- &rts_received,
- &cm_rc);
- /* The only expected return code is CM_OK */
- if (cm_rc != CM_OK)
- return cpicerr_handle_rc(cpicerr, MSG_CMSEND, cm_rc);
- /* this falls through to the receive code!!! */
- case CM_RECEIVE_STATE:
- max_receive_len = 3;
- cmrcv (cm_conv_id,
- buffer,
- &max_receive_len,
- &what_received,
- &received_len,
- &status_received,
- &rts_received,
- &cm_rc);
- if (cm_rc == CM_OK) {
- if (what_received != CM_NO_DATA_RECEIVED) {
- if (received_len > 2 && buffer[0]==CPICERR_EXCHANGE_VERSION) {
- *partner_major_version = buffer[1];
- *partner_minor_version = buffer[2];
- }
- }
- switch (status_received) {
- case CM_CONFIRM_RECEIVED:
- cmcfmd(cm_conv_id,
- &cm_rc);
- if (cm_rc != CM_OK)
- return cpicerr_handle_rc(cpicerr, MSG_CMCFMD, cm_rc);
- break;
- case CM_SEND_RECEIVED:
- /* This is good, we don't have to do anything. */
- break;
- default:
- ;
- /* should do a reply_error here */
-
- }
- } else {
- return cpicerr_handle_rc(cpicerr, MSG_CMRCV, cm_rc);
- }
- break;
- default:
- /* do a reply error here */
- return UNRECOVERABLE;
- }
-
- if ((conv_state == CM_RECEIVE_STATE) &&
- (status_received == CM_SEND_RECEIVED)) {
- buffer[0] = CPICERR_EXCHANGE_VERSION;
- buffer[1] = cpicerr->major_version;
- buffer[2] = cpicerr->minor_version;
- length = 3;
- cmsend(cm_conv_id,
- buffer,
- &length,
- &rts_received,
- &cm_rc);
- /* The only expected return code is CM_OK */
-
- if (cm_rc != CM_OK)
- return cpicerr_handle_rc(cpicerr, MSG_CMSEND, cm_rc);
-
- cmptr(cm_conv_id,
- &cm_rc);
- if (cm_rc != CM_OK)
- return cpicerr_handle_rc(cpicerr, MSG_CMPTR, cm_rc);
- }
- return RC_OK;
- }
-
- /*****************************************************************************
- *
- * cpicerr_destroy()
- *
- *****************************************************************************/
- void
- cpicerr_destroy(CPICERR * cpicerr)
- {
- cpicerr_free_cpicerr(cpicerr);
- return;
- }
-
-
-
- /*****************************************************************************
- *
- * cpicerr_set_rc_info
- *
- *****************************************************************************/
- void
- cpicerr_set_rc_info(CPICERR * cpicerr,
- CPIC_VERB_INDEX verb_index,
- CM_RETURN_CODE conv_rc)
- /* Store the verb return code information into the cpicerr structure */
- {
- cpicerr->verb_index = verb_index;
- cpicerr->conv_rc = conv_rc;
- }
-
- /*****************************************************************************
- *
- * cpicerr_show_rc
- *
- *****************************************************************************/
- void
- cpicerr_show_rc(CPICERR * cpicerr,
- FILE * target_file)
- {
- fprintf(target_file, "\n Unexpected CPI-C return code encountered...\n");
-
- /*-----------------------------------------------------------------------*
- * Find the CPI-C verb's name, and show it.
- *-----------------------------------------------------------------------*/
- fprintf(target_file, " CPI-C verb name: %s, %s\n",
- cpicerr_get_message(CPIC_VERBS_SHORT,
- (CM_INT32)cpicerr->verb_index),
- cpicerr_get_message(CPIC_VERBS_LONG,
- (CM_INT32)cpicerr->verb_index));
-
- /*-----------------------------------------------------------------------*
- * Find the CPI-C return code's name, and show it.
- *-----------------------------------------------------------------------*/
- fprintf(target_file, " CPI-C return code: %lu, %s\n",
- cpicerr->conv_rc,
- cpicerr_get_message(CPIC_RETURN_CODES, cpicerr->conv_rc));
-
- return;
- }
-
-
- /*****************************************************************************
- *
- * cpicerr_classify_rc
- *
- *****************************************************************************/
- void
- cpicerr_classify_rc (CM_RETURN_CODE conv_rc,
- CPIC_RC_HANDLING * classification)
- {
- switch (conv_rc) {
-
- case CM_ALLOCATE_FAILURE_NO_RETRY:
- /* configuration defect or protocol defect, local or partner */
- case CM_TP_NOT_AVAILABLE_NO_RETRY:
- /* partner program could not be sucessfully started */
- case CM_RESOURCE_FAILURE_NO_RETRY:
- /* communication failure or protocol defect, local or partner */
-
- case CM_DEALLOCATED_ABEND:
- /* unrecoverable error in the partner TP */
- case CM_DEALLOCATED_ABEND_SVC:
- /* unrecoverable error in the partner TP */
- case CM_DEALLOCATED_ABEND_TIMER:
- /* unrecoverable error in the partner TP */
-
- case CM_CONVERSATION_TYPE_MISMATCH:
- case CM_PIP_NOT_SPECIFIED_CORRECTLY:
- case CM_SYNC_LVL_NOT_SUPPORTED_LU:
- case CM_SYNC_LVL_NOT_SUPPORTED_PGM:
- case CM_TPN_NOT_RECOGNIZED:
- /* configuration defect or mismatch with the partner */
-
- case CM_OK:
- /* application design defect, local or partner program */
- case CM_DEALLOCATED_NORMAL:
- /* TP design defect, local or partner program */
- case CM_PARAMETER_ERROR:
- /* local program design or coding defect */
- case CM_PROGRAM_PARAMETER_CHECK:
- /* local program design or coding defect */
- case CM_PROGRAM_STATE_CHECK:
- /* local program design or coding defect */
- *classification = UNRECOVERABLE;
- break;
-
- case CM_ALLOCATE_FAILURE_RETRY:
- /* configuration defect or route temporarily down */
- case CM_TP_NOT_AVAILABLE_RETRY:
- /* congestion at the partner operating system */
- case CM_RESOURCE_FAILURE_RETRY:
- /* route temporarily down */
- *classification = RETRY_CONV;
- break;
-
- case CM_UNSUCCESSFUL:
- /* verb could not be completed now */
- *classification = RETRY_VERB;
- break;
-
- case CM_PROGRAM_ERROR_NO_TRUNC:
- case CM_SVC_ERROR_NO_TRUNC:
- /* partner failed while building a record to send */
- case CM_PROGRAM_ERROR_PURGING:
- case CM_SVC_ERROR_PURGING:
- /* partner failed while processing a received record */
- case CM_PROGRAM_ERROR_TRUNC:
- case CM_SVC_ERROR_TRUNC:
- /* partner failed after partially sending a record */
- *classification = ERROR_RECEIVED;
- break;
-
- case CM_PRODUCT_SPECIFIC_ERROR:
- /********************************/
- /* Examine each of these. */
- /* In some cases, you may want */
- /* to return CONTINUE. */
- /********************************/
- *classification = UNRECOVERABLE;
- break;
-
- case CM_SECURITY_NOT_VALID:
- *classification = SECURITY_NOT_VALID;
- break;
-
- case CM_RESOURCE_FAILURE_RETRY_BO:
- /********************************/
- /* Syncpoint values */
- /********************************/
- *classification = RETRY_CONV_BO;
- break;
-
- case CM_TAKE_BACKOUT:
- /********************************/
- /* Syncpoint values */
- /********************************/
- *classification = BACKOUT_RECEIVED;
- break;
-
- case CM_DEALLOCATED_ABEND_BO:
- case CM_DEALLOCATED_ABEND_SVC_BO:
- case CM_DEALLOCATED_ABEND_TIMER_BO:
- case CM_RESOURCE_FAIL_NO_RETRY_BO:
- case CM_DEALLOCATED_NORMAL_BO:
- /********************************/
- /* Syncpoint values */
- /********************************/
- *classification = UNRECOVERABLE_BO;
- break;
-
- default:
- *classification = UNRECOVERABLE;
- break;
- }
- return;
- }
-
-
-
-
-
-
-
- /*****************************************************************************
- *
- * cpicerr_log_cpicerr()
- *
- *****************************************************************************/
- int
- cpicerr_log_cpicerr(CPICERR * cpicerr)
- {
- int rc; /* return value */
- FILE *log_file; /* log file handle */
- unsigned count; /* used to extract text strings */
- char filepath[256]; /* actual file path for logging */
- char last_char;
-
- if (cpicerr != (CPICERR *)NULL) {
-
- /*-------------------------------------------------------------------*
- * Save the time of the call to this procedure.
- *-------------------------------------------------------------------*/
- #ifndef TIME_NOT_SUPPORTED
- time(&(cpicerr->program_error_time));
- #endif
-
- filepath[0] = '\0';
- if (cpicerr->log_file_path != NULL) {
- strcpy(filepath, cpicerr->log_file_path);
- last_char =
- cpicerr->log_file_path[strlen(cpicerr->log_file_path)-1];
- if (!(last_char == '\\' || last_char == '/')) {
- strcat(filepath, "/");
- }
- }
- if (cpicerr->log_file_name != NULL) {
- strcat(filepath, cpicerr->log_file_name);
- }
-
- if ((strlen(filepath) == 0) ||
- ((log_file = fopen(filepath, "a")) == NULL )) {
- log_file = stderr;
- }
-
- if (cpicerr->program_name != NULL) {
- fprintf(log_file, " CPI-C error in program: \"%s\"",
- cpicerr->program_name);
- }
-
-
- if (cpicerr->program_info != NULL) {
- fprintf(log_file, ", %s", cpicerr->program_info);
- }
- fprintf(log_file, "\n");
-
- if (cpicerr->major_version != 0 || cpicerr->minor_version != 0) {
- fprintf(log_file, " Program version: %u.%u\n",
- (unsigned int)cpicerr->major_version,
- (unsigned int)cpicerr->minor_version);
- }
-
-
- cpicerr_show_rc(cpicerr, log_file);
-
- fprintf(log_file, " CPI-C conversation ID: ");
-
- for (count = 0; count<sizeof(cpicerr->conversation_id); count++ ) {
- fprintf(log_file, "%02X",
- (unsigned int)cpicerr->conversation_id[count]);
- }
- fprintf(log_file, "\n");
-
- fprintf(log_file, "CPI-C conversation state: %lu, %s\n",
- cpicerr->conversation_state,
- cpicerr_get_message(CPIC_STATES_CONV, cpicerr->conversation_state));
-
- fprintf(log_file, " CPI-C conversation type: %lu, %s\n",
- cpicerr->conversation_type,
- cpicerr_get_message( CPIC_CONV_TYPES, cpicerr->conversation_type));
-
- fprintf(log_file, " Conversation sync level: %lu, %s\n",
- cpicerr->sync_level,
- cpicerr_get_message( CPIC_SYNC_LEVELS, cpicerr->sync_level));
-
- if (cpicerr->mode_name[0] != '\0') {
- cpicerr->mode_name[(int)cpicerr->mode_name_length] = '\0';
- }
-
- if (cpicerr->partner_LU_name[0] != '\0') {
- cpicerr->partner_LU_name[(int)cpicerr->partner_LU_name_length]
- = '\0';
- }
-
- fprintf(log_file, " Partner LU name: %s\n",
- cpicerr->partner_LU_name);
- fprintf(log_file, " Mode name: %s\n",
- cpicerr->mode_name);
-
- #ifndef TIME_NOT_SUPPORTED
- fprintf(log_file, " Program start time: %s",
- ctime(&(cpicerr->program_start_time)));
- fprintf(log_file, " Program error time: %s\n",
- ctime(&(cpicerr->program_error_time)));
- #endif
-
- fclose(log_file);
-
- rc = 0;
- } else {
- rc = 1;
- }
-
- return rc;
- }
-
- /*****************************************************************************
- *
- * cpicerr_free_cpicerr()
- *
- *****************************************************************************/
- void
- cpicerr_free_cpicerr(CPICERR * cpicerr)
- {
- if (cpicerr != NULL) {
- if (cpicerr->program_name != NULL) {
- free(cpicerr->program_name);
- }
-
- if (cpicerr->program_info != NULL) {
- free(cpicerr->program_info);
- }
-
- if (cpicerr->log_file_name != NULL) {
- free(cpicerr->log_file_name);
- }
-
- if (cpicerr->log_file_path != NULL) {
- free(cpicerr->log_file_path);
- }
-
- free(cpicerr);
- }
-
- return;
- }
-
-
-
- CPICERR_MESSAGE cpicerr_verbs_short[] = {
- MSG_CMACCP, "CMACCP",
- MSG_CMALLC, "CMALLC",
- MSG_CMCFM, "CMCFM",
- MSG_CMCFMD, "CMCFMD",
- MSG_CMDEAL, "CMDEAL",
- MSG_CMECS, "CMECS",
- MSG_CMECT, "CMECT",
- MSG_CMEMN, "CMEMN",
- MSG_CMEPLN, "CMEPLN",
- MSG_CMESL, "CMESL",
- MSG_CMFLUS, "CMFLUS",
- MSG_CMINIT, "CMINIT",
- MSG_CMPTR, "CMPTR",
- MSG_CMRCV, "CMRCV",
- MSG_CMRTS, "CMRTS",
- MSG_CMSCT, "CMSCT",
- MSG_CMSDT, "CMSDT",
- MSG_CMSED, "CMSED",
- MSG_CMSEND, "CMSEND",
- MSG_CMSERR, "CMSERR",
- MSG_CMSF, "CMSF",
- MSG_CMSLD, "CMSLD",
- MSG_CMSMN, "CMSMN",
- MSG_CMSPLN, "CMSPLN",
- MSG_CMSPTR, "CMSPTR",
- MSG_CMSRC, "CMSRC",
- MSG_CMSRT, "CMSRT",
- MSG_CMSSL, "CMSSL",
- MSG_CMSST, "CMSST",
- MSG_CMSTPN, "CMSTPN",
- MSG_CMTRTS, "CMTRTS",
- MSG_XCSCSU, "XCSCSU",
- MSG_XCSCSP, "XCSCSP",
- MSG_XCSCST, "XCSCST",
- MAX_MESSAGE, "ERROR "
- };
-
- CPICERR_MESSAGE cpicerr_verbs_long[] = {
- MSG_CMACCP, "Accept_Conversation",
- MSG_CMALLC, "Allocate",
- MSG_CMCFM, "Confirm",
- MSG_CMCFMD, "Confirmed",
- MSG_CMDEAL, "Deallocate",
- MSG_CMECS, "Extract_Conversation_State",
- MSG_CMECT, "Extract_Conversation_Type",
- MSG_CMEMN, "Extract_Mode_Name",
- MSG_CMEPLN, "Extract_Partner_LU_Name",
- MSG_CMESL, "Extract_Sync_Level",
- MSG_CMFLUS, "Flush",
- MSG_CMINIT, "Initialize_Conversation",
- MSG_CMPTR, "Prepare_To_Receive",
- MSG_CMRCV, "Receive",
- MSG_CMRTS, "Request_To_Send",
- MSG_CMSCT, "Set_Conversation_Type",
- MSG_CMSDT, "Set_Deallocate_Type",
- MSG_CMSED, "Set_Error_Direction",
- MSG_CMSEND, "Send_Data",
- MSG_CMSERR, "Send_Error",
- MSG_CMSF, "Set_Fill",
- MSG_CMSLD, "Set_Log_Data",
- MSG_CMSMN, "Set_Mode_Name",
- MSG_CMSPLN, "Set_Partner_LU_Name",
- MSG_CMSPTR, "Set_Prepare_To_Receive_Type",
- MSG_CMSRC, "Set_Return_Control",
- MSG_CMSRT, "Set_Receive_Type",
- MSG_CMSSL, "Set_Sync_Level",
- MSG_CMSST, "Set_Send_Type",
- MSG_CMSTPN, "Set_TP_Name",
- MSG_CMTRTS, "Test_Request_To_Send_Received",
- MSG_XCSCSU, "Set Conversation Security Userid",
- MSG_XCSCSP, "Set Conversation Security Password",
- MSG_XCSCST, "Set Conversation Security Type",
- MAX_MESSAGE, "Invalid verb name"
- };
-
- CPICERR_MESSAGE cpicerr_return_codes[] = {
- CM_OK, "CM_OK",
- CM_ALLOCATE_FAILURE_NO_RETRY, "CM_ALLOCATE_FAILURE_NO_RETRY",
- CM_ALLOCATE_FAILURE_RETRY, "CM_ALLOCATE_FAILURE_RETRY",
- CM_CONVERSATION_TYPE_MISMATCH, "CM_CONVERSATION_TYPE_MISMATCH",
- CM_PIP_NOT_SPECIFIED_CORRECTLY, "CM_PIP_NOT_SPECIFIED_CORRECTLY",
- CM_SECURITY_NOT_VALID, "CM_SECURITY_NOT_VALID",
- CM_SYNC_LVL_NOT_SUPPORTED_LU, "CM_SYNC_LVL_NOT_SUPPORTED_LU",
- CM_SYNC_LVL_NOT_SUPPORTED_PGM, "CM_SYNC_LVL_NOT_SUPPORTED_PGM",
- CM_TPN_NOT_RECOGNIZED, "CM_TPN_NOT_RECOGNIZED",
- CM_TP_NOT_AVAILABLE_NO_RETRY, "CM_TP_NOT_AVAILABLE_NO_RETRY",
- CM_TP_NOT_AVAILABLE_RETRY, "CM_TP_NOT_AVAILABLE_RETRY",
- CM_DEALLOCATED_ABEND, "CM_DEALLOCATED_ABEND",
- CM_DEALLOCATED_NORMAL, "CM_DEALLOCATED_NORMAL",
- CM_PARAMETER_ERROR, "CM_PARAMETER_ERROR",
- CM_PRODUCT_SPECIFIC_ERROR, "CM_PRODUCT_SPECIFIC_ERROR",
- CM_PROGRAM_ERROR_NO_TRUNC, "CM_PROGRAM_ERROR_NO_TRUNC",
- CM_PROGRAM_ERROR_PURGING, "CM_PROGRAM_ERROR_PURGING",
- CM_PROGRAM_ERROR_TRUNC, "CM_PROGRAM_ERROR_TRUNC",
- CM_PROGRAM_PARAMETER_CHECK, "CM_PROGRAM_PARAMETER_CHECK",
- CM_PROGRAM_STATE_CHECK, "CM_PROGRAM_STATE_CHECK",
- CM_RESOURCE_FAILURE_NO_RETRY, "CM_RESOURCE_FAILURE_NO_RETRY",
- CM_RESOURCE_FAILURE_RETRY, "CM_RESOURCE_FAILURE_RETRY",
- CM_UNSUCCESSFUL, "CM_UNSUCCESSFUL",
- CM_DEALLOCATED_ABEND_SVC, "CM_DEALLOCATED_ABEND_SVC",
- CM_DEALLOCATED_ABEND_TIMER, "CM_DEALLOCATED_ABEND_TIMER",
- CM_SVC_ERROR_NO_TRUNC, "CM_SVC_ERROR_NO_TRUNC",
- CM_SVC_ERROR_PURGING, "CM_SVC_ERROR_PURGING",
- CM_SVC_ERROR_TRUNC, "CM_SVC_ERROR_TRUNC",
- CM_TAKE_BACKOUT, "CM_TAKE_BACKOUT",
- CM_DEALLOCATED_ABEND_BO, "CM_DEALLOCATED_ABEND_BO",
- CM_DEALLOCATED_ABEND_SVC_BO, "CM_DEALLOCATED_ABEND_SVC_BO",
- CM_DEALLOCATED_ABEND_TIMER_BO, "CM_DEALLOCATED_ABEND_TIMER_BO",
- CM_RESOURCE_FAIL_NO_RETRY_BO, "CM_RESOURCE_FAIL_NO_RETRY_BO",
- CM_RESOURCE_FAILURE_RETRY_BO, "CM_RESOURCE_FAILURE_RETRY_BO",
- CM_DEALLOCATED_NORMAL_BO, "CM_DEALLOCATED_NORMAL_BO",
- MAX_MESSAGE, "Invalid Return Code Value"
- };
-
- CPICERR_MESSAGE cpicerr_rc_classes[] = {
- BACKOUT_RECEIVED, "BACKOUT_RECEIVED",
- CONTINUE, "CONTINUE",
- ERROR_RECEIVED, "ERROR_RECEIVED",
- SECURITY_NOT_VALID, "SECURITY_NOT_VALID",
- RETRY_CONV, "RETRY_CONVERSATION",
- RETRY_CONV_BO, "RETRY_CONVERSATION_BACKOUT",
- RETRY_VERB, "RETRY_LAST_VERB",
- UNRECOVERABLE, "UNRECOVERABLE",
- UNRECOVERABLE_BO, "UNRECOVERABLE_BACKOUT",
- MAX_MESSAGE, "Invalid Return Code Class"
- };
-
- CPICERR_MESSAGE cpicerr_states_conv[] = {
- CM_INITIALIZE_STATE, "Initialize state",
- CM_SEND_STATE, "Send state",
- CM_RECEIVE_STATE, "Receive state",
- CM_SEND_PENDING_STATE, "Send pending state",
- CM_CONFIRM_STATE, "Confirm state",
- CM_CONFIRM_SEND_STATE, "Confirm send state",
- CM_CONFIRM_DEALLOCATE_STATE, "Confirm deallocate state",
- CM_DEFER_RECEIVE_STATE, "Defer receive state",
- CM_DEFER_DEALLOCATE_STATE, "Defer deallocate state",
- CM_SYNC_POINT_STATE, "Sync point state",
- CM_SYNC_POINT_SEND_STATE, "Sync point send state",
- CM_SYNC_POINT_DEALLOCATE_STATE, "Sync point deallocate state",
- CMECS_NOT_SUPPORTED, "CMECS not supported",
- MAX_MESSAGE, "Invalid Conversation State value"
- };
-
- CPICERR_MESSAGE cpicerr_sync_levels[] = {
- CM_NONE, "None",
- CM_CONFIRM, "Confirm",
- CM_SYNC_POINT, "Sync Point",
- MAX_MESSAGE, "Invalid Sync Level value"
- };
-
- CPICERR_MESSAGE cpicerr_conv_types[] = {
- CM_BASIC_CONVERSATION , "Basic",
- CM_MAPPED_CONVERSATION, "Mapped",
- CMECT_NOT_SUPPORTED, "CMECT not supported",
- MAX_MESSAGE, "Invalid conversation type value"
- };
-
- CPICERR_MESSAGE_LIST message_list[] = {
- CPIC_SYNC_LEVELS, cpicerr_sync_levels,
- CPIC_CONV_TYPES, cpicerr_conv_types,
- CPIC_STATES_CONV, cpicerr_states_conv,
- CPIC_RC_CLASSES, cpicerr_rc_classes,
- CPIC_RETURN_CODES, cpicerr_return_codes,
- CPIC_VERBS_SHORT, cpicerr_verbs_short,
- CPIC_VERBS_LONG, cpicerr_verbs_long,
- MAX_MESSAGE, NULL
- };
-
- /*****************************************************************************
- *
- * cpicerr_get_message()
- *
- *****************************************************************************/
- char *
- cpicerr_get_message(CPICERR_MESSAGE_TYPE message_type, CM_INT32 index)
- {
- unsigned int count; /* counter through the array */
-
- CPICERR_MESSAGE * messages;
-
- for (count = 0; message_list[count].type < MAX_MESSAGE ; count++ ) {
- if (message_list[count].type == message_type) break;
- }
-
- if ( (messages = message_list[count].list) == NULL ) {
- return "Message list not found.";
- }
-
- for (count = 0; messages[count].index < MAX_MESSAGE; count++) {
- if (messages[count].index == index) break;
- }
- return messages[count].message;
- }
-
-
-
- /*****************************************************************************
- *
- * cpicerr_show_product_info
- *
- *****************************************************************************/
- void
- cpicerr_show_product_info(CPICERR * cpicerr,
- FILE * target_file)
- {
- FILE * temp;
- temp = target_file; /* avoids warnings */
-
- if (cpicerr->conv_rc == CM_ALLOCATE_FAILURE_NO_RETRY ||
- cpicerr->conv_rc == CM_ALLOCATE_FAILURE_RETRY ) {
- if (get_machine_mode()) {
- #ifdef GET_OS2_SENSE_DATA
- cpicerr_os2_appc_allocate(cpicerr, target_file);
- #endif
- }
-
- }
- }
-
- #ifdef GET_OS2_SENSE_DATA
-
- cpicerr_os2_appc_allocate(CPICERR * cpicerr,
- FILE * target_file)
- /*
- * This procedure retries the allocate that failed in CPI-C. We are not
- * retrying the allocate to establish the connection, but to get more
- * error information about why the first allocate failed.
- *
- * The OS/2 APPC api is used to extract the sense data, which provides
- * a more specify reason for an allocation failure.
- */
- {
- TP_STARTED tp_started; /* Declare a verb control block */
- TP_STARTED *ptr_tp_started = (TP_STARTED *)&tp_started;
- USHORT length; /* length of lu_alias */
- char plu_alias[8+1];
- char fqplu_name[17+1];
-
- ALLOCATE allocate; /* Declare a verb control block */
- ALLOCATE *ptr_allocate = (ALLOCATE *)&allocate;
-
- TP_ENDED tp_ended; /* Declare a verb control block */
- TP_ENDED *ptr_tp_ended = (TP_ENDED *)&tp_ended;
-
-
- CLEAR_VCB(tp_started); /* Zero the verb control block */
- tp_started.opcode = AP_TP_STARTED; /* APPC verb - TP_STARTED */
-
- memset( tp_started.lu_alias, (int)'\0', sizeof(tp_started.lu_alias));
-
- BLANK_STRING(tp_started.tp_name); /* Set 64-byte string to blanks */
- ascii_to_ebcdic_field(tp_started.tp_name,
- sizeof(tp_started.tp_name));
-
- APPC ((ULONG) (TP_STARTED far *)ptr_tp_started); /* Issue the verb */
-
- if (tp_started.primary_rc == AP_OK) {
- CLEAR_VCB(allocate); /* Zero the vcb */
- allocate.opcode = AP_B_ALLOCATE; /* Verb - ALLOCATE */
- allocate.opext = AP_MAPPED; /* Basic Conversation type */
-
- /* Set the TP_ID */
- memcpy (allocate.tp_id, tp_started.tp_id, sizeof(allocate.tp_id));
- allocate.sync_level = AP_CONFIRM; /* Sync level-confirm */
- allocate.rtn_ctl = AP_WHEN_SESSION_FREE;/* avoid deadlock */
- allocate.security = AP_NONE; /* Set security type */
-
- if (!parse_destination(cpicerr->partner_LU_name,
- plu_alias,
- fqplu_name)) {
- if ((length = strlen(plu_alias)) != 0) {
- BLANK_STRING(allocate.plu_alias);
- memcpy ( allocate.plu_alias,
- plu_alias,
- min(length, sizeof(allocate.plu_alias)));
- /* Set PLU_ALIAS */
- } else {
- memset (allocate.plu_alias,(int)'\0',sizeof(allocate.plu_alias));
- BLANK_STRING(allocate.fqplu_name); /* Set FQ PLU NAME */
- memcpy ( allocate.fqplu_name,
- fqplu_name,
- min(strlen(fqplu_name), sizeof(allocate.fqplu_name)));
- TOUPPER_STRING(allocate.fqplu_name, 17);
- ascii_to_ebcdic_field(allocate.fqplu_name,
- sizeof(allocate.fqplu_name));
- }
-
-
- } else {
- BLANK_STRING(allocate.plu_alias);
- memcpy ( allocate.plu_alias,
- "UNKNOWN",
- 7);
- }
-
-
- BLANK_STRING(allocate.tp_name); /* Set 64-byte string to blanks */
- ascii_to_ebcdic_field(allocate.tp_name,
- sizeof(allocate.tp_name));
-
- BLANK_STRING(allocate.mode_name); /* Set 8-byte string to blanks */
- memcpy ( allocate.mode_name,
- cpicerr->mode_name,
- min(strlen(cpicerr->mode_name),
- sizeof(allocate.mode_name)));
- TOUPPER_STRING(allocate.mode_name, 8);
- ascii_to_ebcdic_field(allocate.mode_name,
- sizeof(allocate.mode_name));
-
- APPC((ULONG) (ALLOCATE far *) ptr_allocate); /* Issue the verb */
-
- if (allocate.primary_rc != AP_OK) {
- fprintf(target_file,
- "\t OS/2 Sense Data: %08lX\n", SWAP4(allocate.sense_data));
-
- }
-
- } else { /* Save the returned tp_id */
- return (tp_started.primary_rc);
- }
- CLEAR_VCB(tp_ended); /* Zero the verb control block */
- tp_ended.opcode = AP_TP_ENDED; /* Set the verb opcode */
- /* Set the tp_id */
- memcpy (tp_ended.tp_id, tp_started.tp_id, sizeof(tp_ended.tp_id));
- tp_ended.type = AP_SOFT; /* type: AP_HARD or AP_SOFT */
-
- APPC((ULONG) (TP_ENDED far *) ptr_tp_ended); /* Issue the verb. */
- }
-
-
-
- USHORT
- parse_destination(char * in_string,
- char * plu_alias,
- char * fqplu_name)
- /*
- * This procedure is used by cpicerr_os2_appc_allocate verb
- */
- {
- if (strchr(in_string, '.') != NULL) {
- if (in_string[0] == '.') {
- in_string++;
- }
- strcpy(fqplu_name, in_string);
- plu_alias[0] = '\0';
- } else {
- strcpy(plu_alias, in_string);
- fqplu_name[0] = '\0';
- }
- return 0;
-
- }
-
- #endif
-